﻿using CoreModule;
using Flurl;
using Microsoft.Extensions.Logging;
using NPOI.SS.Formula.Functions;
using Prism.Mvvm;
using Prism.Navigation;
using Prism.Regions;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
namespace UIModule.ViewModels
{
    /// <summary>
    /// 测量结果
    /// </summary>
    public class MeasurementResultViewModel
        : BindableBase
        , IDestructible
        , IRegionMemberLifetime
        , INavigationAware
        ,IConfirmNavigationRequest
    {
        /// <summary>
        /// 区域管理器
        /// </summary>
        IRegionManager RegionManager { get; set; }
 
        /// <summary>
        /// 定时器
        /// </summary>
        DispatcherTimer DispatcherTimer { get; set; }

        /// <summary>
        /// 测量信息（每次）
        /// </summary>
        public MeasurementResultInfo MeasurementResultInfo { get; set; } = new MeasurementResultInfo();

        /// <summary>
        /// 患者信息
        /// </summary>
        public PatientInfo PatientInfo { get; set; } = new PatientInfo();

        /// <summary>
        /// 结果url
        /// </summary>
        public string ResultUrl { get; set; } = string.Empty;

        /// <summary>
        /// 保存测量结果 并 回到 测量首页
        /// </summary>
        public ICommand SaveAndGoMeasurementHomeCommand => new Prism.Commands.DelegateCommand(SaveAndGoMeasurementHome);

        /// <summary>
        /// 
        /// </summary>
        public ICommand CancelAndGoMeasurementHomeCommand => new Prism.Commands.DelegateCommand(CancelAndGoMeasurement);


        /// <summary>
        /// 配置信息
        /// </summary>
        public CoreModule.FunctionCheckConfigurationInfo FunctionCheckConfigurationInfo { get; set; }= FunctionCheckConfigurationInfo.Load();


        /// <summary>
        /// 心跳
        /// </summary>
        public float HeartBeatOpacity { get; set; } = 1.0f;
        public Visibility HeartBeatVisibility { get; set; } = Visibility.Collapsed;

        public Visibility DynamicColumnVisibility { get; set; } = Visibility.Collapsed;

        /// <summary>
        /// 
        /// </summary>
        public void CancelAndGoMeasurement()
        {
            RegionManager.RequestNavigate(CoreConstant.MainRegion, CoreConstant.MeasurementHomeView);
        }

        /// <summary>
        /// 
        /// </summary>
        public bool SaveFlag = false;

        /// <summary>
        /// 提示
        /// </summary>
        public void SaveAndGoMeasurementHome()
        {
            this.SaveFlag = true;
            this.PatientInfo.Height = MeasurementResultInfo.Height;

            this.PatientInfo.Weight = MeasurementResultInfo.Weight;
            
            this.PatientInfo.MobilePhone = MeasurementResultInfo.MobilePhone;
           

            this.Notifier.ShowSuccess("保存成功");

          
            MeasurementResultInfo.ShowRespiratoryRate = FunctionCheckConfigurationInfo.RespiratoryRate;
            MeasurementResultInfo.ShowPain = FunctionCheckConfigurationInfo.Pain;
            MeasurementResultInfo.ShowBloodSugar = FunctionCheckConfigurationInfo.BloodSugar;

            MeasurementResultInfo.ShowHeight = FunctionCheckConfigurationInfo.Height_Weight_BMI;
            MeasurementResultInfo.ShowWeight = FunctionCheckConfigurationInfo.Height_Weight_BMI;
            MeasurementResultInfo.ShowBMI = FunctionCheckConfigurationInfo.Height_Weight_BMI;

            MeasurementResultInfo.ShowEWS = FunctionCheckConfigurationInfo.EWS;
            MeasurementResultInfo.ShowConsciousness = FunctionCheckConfigurationInfo.Consciousness;
            MeasurementResultInfo.ShowMobilePhone = FunctionCheckConfigurationInfo.MobilePhone;


            var dbColumnConfigurationInfos = DbColumnManager.Load().DbColumnConfigurationInfos;


            for (int i = 0; i < 20; i++)
            {
                var dbColumnConfigurationInfo = dbColumnConfigurationInfos[i];

                var columnName = string.Format("Cln{0}", i);
           
                var titleField = MeasurementResultInfo.GetType().GetProperty(string.Format("Cln{0}Title", i));

                var sortIndexField = MeasurementResultInfo.GetType().GetProperty(string.Format("Cln{0}SortIndex", i));

                titleField.SetValue(MeasurementResultInfo, dbColumnConfigurationInfo.FieldName);
                sortIndexField.SetValue(MeasurementResultInfo, dbColumnConfigurationInfo.SortIndex);

            }
            
            ///用于 HIS （与 血压类似）
            DeviceManager.SubmitResult(new ComposeResultInfoEventArgs(new RecognitionResultInfo() { PatientInfo=this.PatientInfo}, MeasurementResultInfo));

            RegionManager.RequestNavigate(CoreConstant.MainRegion, CoreConstant.MeasurementHomeView);

        }
        /// <summary>
        /// 设备管理器
        /// </summary>
        IDeviceManager DeviceManager { get; set; }
        /// <summary>
        /// 
        /// </summary>
        static int Frequency = 10;
        /// <summary>
        /// 
        /// </summary>
        int HeartBeatIndex = 0;

        INotifier Notifier { get; set; }
        /// <summary>
        /// 日志
        /// </summary>
        ILogger Logger { get; set; }
        public MeasurementResultViewModel(
            INotifier notifier,
            ILogger logger,
            IDeviceManager deviceManager,
            IRegionManager regionManager,
            IConfigurationManager systemConfiguration
            ,IWindowLifetime windowLifetime)
        {
            Notifier = notifier;
            Logger = logger;
            RegionManager = regionManager;
            DeviceManager = deviceManager;
            DispatcherTimer = new DispatcherTimer();
            DispatcherTimer.Interval = TimeSpan.FromMilliseconds(1000/ Frequency/2);
            DispatcherTimer.Tick += DispatcherTimer_Tick;
            DispatcherTimer.Start();
            DeviceManager.MeasurementResultCompleted += DeviceManager_MeasurementResultCompleted;
            DeviceManager.RecognitionResultCompleted += DeviceManager_RecognitionResultCompleted;
            windowLifetime.RegionViewKind = RegionViewKind.MeasurementResult;
        }

        /// <summary>
        /// 脉率 
        /// </summary>
        public bool PulseRateIsCompleted { get; set; } = true;

        /// <summary>
        /// 
        /// </summary>
        public static string UrlRoot = "https://t.yuwell.com/TunnelSphygmomanometer/#/vitalsign?";
         

        public ICommand UpdateResultUrlImageCommand => new Prism.Commands.DelegateCommand(() => { });

         
        /// <summary>
        /// 
        /// </summary>
        private void UpdateResultUrlImage()
        {

            System.Collections.Generic.Dictionary<string, object> 
                keyValuePairs = new System.Collections.Generic.Dictionary<string, object>();

            keyValuePairs.Add("a", this.PatientInfo.PatientName);
            keyValuePairs.Add("b", (int)this.PatientInfo.Sex);
            keyValuePairs.Add("c", (int)this.PatientInfo.Age);
            keyValuePairs.Add("d", DateTime.Now.ToString("yyyy-MM-dd HH:mm"));
            

            keyValuePairs.Add("e", this.MeasurementResultInfo.SBP==0?string.Empty:this.MeasurementResultInfo.SBP);
         

            keyValuePairs.Add("f", this.MeasurementResultInfo.DBP == 0 ? string.Empty : this.MeasurementResultInfo.DBP);
            

            keyValuePairs.Add("g", this.MeasurementResultInfo.PulseRate == 0 ? string.Empty : this.MeasurementResultInfo.PulseRate);
           

            keyValuePairs.Add("h", this.MeasurementResultInfo.BloodOxygen == 0 ? string.Empty : this.MeasurementResultInfo.BloodOxygen);
           
            keyValuePairs.Add("i", this.MeasurementResultInfo.PerfusionIndex == 0 ? string.Empty : this.MeasurementResultInfo.PerfusionIndex);

            keyValuePairs.Add("j", this.MeasurementResultInfo.Temperature == 0 ? string.Empty : this.MeasurementResultInfo.Temperature);

            //keyValuePairs.Add("k", this.MeasurementResultInfo.RespiratoryRate);
            //keyValuePairs.Add("l", this.MeasurementResultInfo.Pain      );
            //keyValuePairs.Add("m", this.MeasurementResultInfo.BloodSugar);
            //keyValuePairs.Add("n", this.MeasurementResultInfo.Height);
            //keyValuePairs.Add("o", this.MeasurementResultInfo.Weight);
            //keyValuePairs.Add("p", this.MeasurementResultInfo.BMI==0?string.Empty: this.MeasurementResultInfo.BMI.ToString("F2"));
            //keyValuePairs.Add("q", this.MeasurementResultInfo.EWS);
            //keyValuePairs.Add("r", this.MeasurementResultInfo.Consciousness);
            //keyValuePairs.Add("s", this.MeasurementResultInfo.MobilePhone);

            var path= string.Join("&", keyValuePairs.Select(item =>Url.Encode( item.Key) + "=" + Url.Encode( item.Value.ToString())));

            this.ResultUrl = UrlRoot + path;

            this.RaisePropertyChanged(nameof(this.ResultUrl));

        }
    
        /// <summary>
        /// 更新 测量信息
        /// </summary>
        /// <param name="e"></param>
        public void UpdateMeasurementResult(MeasurementResultInfoEventArgs e)
        {

            var needUpdateResultUrlImageFlag = false;

             var measurementResultKind = e.MeasurementResultKind;
            var measurementResultInfo = e.MeasurementResultInfo;
            if (measurementResultKind== MeasurementResultKind.None)
            {
                return;
            }
            if (measurementResultKind.HasFlag(MeasurementResultKind.DBP_RES))
            {
                this.MeasurementResultInfo.DBP = measurementResultInfo.DBP;
                this.MeasurementResultInfo.UpdateDbpStatus();
                this.MeasurementResultInfo.UpdatePressureLevel();
                needUpdateResultUrlImageFlag = true;
                
            }
            if (measurementResultKind.HasFlag(MeasurementResultKind.SBP_RES))
            {
                this.MeasurementResultInfo.SBP = measurementResultInfo.SBP;
                this.MeasurementResultInfo.UpdateSbpStatus();
                this.MeasurementResultInfo.UpdatePressureLevel();
                needUpdateResultUrlImageFlag = true;
            }

            if (measurementResultKind.HasFlag(MeasurementResultKind.PulseRate_RES))
            {
                this.MeasurementResultInfo.PulseRate = measurementResultInfo.PulseRate;
                this.PulseRateIsCompleted = true;
                needUpdateResultUrlImageFlag = true;
            }
            if (measurementResultKind.HasFlag(MeasurementResultKind.PulseRate_MSR))
            {
                this.MeasurementResultInfo.PulseRate = measurementResultInfo.PulseRate;
                this.PulseRateIsCompleted = false;
            }
            if (measurementResultKind.HasFlag(MeasurementResultKind.BloodOxygen_RES))
            {
                this.MeasurementResultInfo.BloodOxygen = measurementResultInfo.BloodOxygen;
                this.MeasurementResultInfo.UpdateBloodOxygenStatus();
                needUpdateResultUrlImageFlag = true;

                this.DynamicColumnVisibility = Visibility.Collapsed;
                this.RaisePropertyChanged(nameof(this.DynamicColumnVisibility));

              
            }
            if (measurementResultKind.HasFlag(MeasurementResultKind.BloodOxygen_MSR))
            {
                this.MeasurementResultInfo.BloodOxygen = measurementResultInfo.BloodOxygen;
                this.MeasurementResultInfo.UpdateBloodOxygenStatus();
                 
                this.DynamicColumnVisibility = Visibility.Visible;
                this.RaisePropertyChanged(nameof(this.DynamicColumnVisibility));

             

            }
            if (measurementResultKind.HasFlag(MeasurementResultKind.PerfusionIndex_MSR))
            {
                this.MeasurementResultInfo.PerfusionIndex = measurementResultInfo.PerfusionIndex;
                this.MeasurementResultInfo.UpdatePerfusionIndexStatus();
            }
            if (measurementResultKind.HasFlag(MeasurementResultKind.PerfusionIndex_RES))
            {
                this.MeasurementResultInfo.PerfusionIndex = measurementResultInfo.PerfusionIndex;
                this.MeasurementResultInfo.UpdatePerfusionIndexStatus();
                needUpdateResultUrlImageFlag = true;
            }
            if (measurementResultKind.HasFlag(MeasurementResultKind.Temperature_RES))
            {
                this.MeasurementResultInfo.Temperature = measurementResultInfo.Temperature;
                this.MeasurementResultInfo.UpdateTemperatureStatus();
                needUpdateResultUrlImageFlag = true;
            }
            if (measurementResultKind.HasFlag(MeasurementResultKind.MachinePressure))
            {
                this.MeasurementResultInfo.MachinePressure = measurementResultInfo.MachinePressure;
            }

            this.RaisePropertyChanged(nameof(this.MeasurementResultInfo));

           if (needUpdateResultUrlImageFlag)
            {
                this.UpdateResultUrlImage();
            }
        }

        /// <summary>
        /// 收到测量结果
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeviceManager_MeasurementResultCompleted(object sender, MeasurementResultInfoEventArgs e)
        {
            ///不处理 心跳
            if (e.MeasurementResultKind== MeasurementResultKind.None)
            {
                return;
            }
            UpdateMeasurementResult(e);
        }
        /// <summary>
        ///  收到 患者信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeviceManager_RecognitionResultCompleted(object sender, RecognitionResultInfoEventArgs e)
        {
            if (!e.RecognitionResultInfo.IsChanged || e.Cancel)
            {
                return;
            }

            ///之前有患者信息，
            if (this.PatientInfo.IsValid)
            {
                this.Notifier.ShowWarning("当前在测量过程中，请先保存测量结果");

                return;
            }

            this.PatientInfo = e.RecognitionResultInfo.PatientInfo;
            this.PatientInfo.UpdateAgeGroup();
            this.RaisePropertyChanged(nameof(this.PatientInfo));

            this.UpdateResultUrlImage();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DispatcherTimer_Tick(object sender, EventArgs e)
        {
            var pulseRate = this.MeasurementResultInfo.PulseRate;

            if (pulseRate == 0)
            {
                return;
            }

            if (PulseRateIsCompleted )
            {
                HeartBeatVisibility = Visibility.Visible;
                this.RaisePropertyChanged(nameof(HeartBeatVisibility));
                return;
            }

            HeartBeatIndex = HeartBeatIndex + 1;

            if (pulseRate <60)
            {
                pulseRate = 60;
                return;
            }

            if (pulseRate<=60)
            {
                if (HeartBeatIndex  % (Frequency) == 0)
                {
                    HeartBeatVisibility = (HeartBeatVisibility == Visibility.Visible)
                            ? Visibility.Hidden : Visibility.Visible;

                }
            }
            else if (pulseRate>=60 && pulseRate<=80)
            {
                if (HeartBeatIndex % (int)(Frequency*0.8) == 0)
                {
                    HeartBeatVisibility = (HeartBeatVisibility == Visibility.Visible)
                            ? Visibility.Hidden : Visibility.Visible;

                }
            }
            else if (pulseRate >= 80 && pulseRate <= 100)
            {
                if (HeartBeatIndex % (int)(Frequency * 0.7) == 0)
                {
                    HeartBeatVisibility = (HeartBeatVisibility == Visibility.Visible)
                            ? Visibility.Hidden : Visibility.Visible;

                }
            }
            else if (pulseRate >= 100 && pulseRate <= 120)
            {
                if (HeartBeatIndex %(int) (Frequency * 0.5) == 0)
                {
                    HeartBeatVisibility = (HeartBeatVisibility == Visibility.Visible)
                            ? Visibility.Hidden : Visibility.Visible;

                }
            }
            else if (pulseRate >= 120 && pulseRate <= 140)
            {
                if (HeartBeatIndex % (int)(Frequency * 0.4) == 0)
                {
                    HeartBeatVisibility = (HeartBeatVisibility == Visibility.Visible)
                            ? Visibility.Hidden : Visibility.Visible;

                }
            }
            else
            {
                if (HeartBeatIndex % (int)(Frequency * 0.3) == 0)
                {
                    HeartBeatVisibility = (HeartBeatVisibility == Visibility.Visible)
                            ? Visibility.Hidden : Visibility.Visible;

                }
            }
            this.RaisePropertyChanged(nameof(HeartBeatVisibility));

        }
        public bool KeepAlive => false;
     
        

        /// <summary>
        /// 
        /// </summary>
        public void Destroy()
        {

            DeviceManager.RecognitionResultCompleted -= DeviceManager_RecognitionResultCompleted;
            DeviceManager.MeasurementResultCompleted -= DeviceManager_MeasurementResultCompleted;
            DispatcherTimer.Tick -= DispatcherTimer_Tick;
            DispatcherTimer.Stop();


        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="navigationContext"></param>
        /// <returns></returns>
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="navigationContext"></param>
        public void OnNavigatedFrom(NavigationContext navigationContext)
        {

         }

        /// <summary>
        /// 接受 患者信息
        /// </summary>
        /// <param name="navigationContext"></param>
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            var recognitionResultInfo = navigationContext.Parameters
               .GetValue<RecognitionResultInfo>(CoreConstant.RecognitionResultInfoKey);

            this.RaisePropertyChanged(nameof(RecognitionResultInfo));

            if (recognitionResultInfo?.PatientInfo!=null)
            {
                this.PatientInfo = recognitionResultInfo.PatientInfo;
                this.RaisePropertyChanged(nameof(PatientInfo));
                this.UpdateResultUrlImage();
            }

            var measurementResultInfoEventArgs = navigationContext.Parameters
              .GetValue<MeasurementResultInfoEventArgs>(CoreConstant.MeasurementResultInfoEventArgsKey);

            if (measurementResultInfoEventArgs!=null)
            {
                UpdateMeasurementResult(measurementResultInfoEventArgs);
            }
           
            //var sBP = MeasurementResultInfo?.SBP;
            //var dBP = MeasurementResultInfo?.DBP;
            //var pulseRate = MeasurementResultInfo?.PulseRate;
            //var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
            //ResultUrl = $@"https://t.yuwell.com/TunnelSphygmomanometer/#/index?sbp={sBP}&dbp={dBP}&pulse={pulseRate}&time={time}";
            //this.RaisePropertyChanged(nameof(ResultUrl));
            //CoreModule.PatientInfo.Instance = null;
        }

        /// <summary>
        /// 离开时，确认。详细参考 prism (当前自动保存）
        /// </summary>
        /// <param name="navigationContext"></param>
        /// <param name="continuationCallback"></param>
        public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
        {
            continuationCallback(true);
        }
    }
}
